/*
 * HTMLHandler.java
 *
 * Created on 4 September 2006, 1:10
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package fasea.index.filehandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.apache.lucene.document.Field;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.w3c.tidy.Tidy;

import java.io.InputStream;
import org.apache.lucene.document.Document;

/**
 *
 * @author gvasil
 */
class HTMLHandler extends FileHandler {

    public Document getTypedDocument(File file) throws FileHandlerException {
        InputStream is = null;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new FileHandlerException(
                    "File not found: "
                    + file.getAbsolutePath(), e);
        }

        org.apache.lucene.document.Document doc = createDefaultLuceneDocument(file);

        Tidy tidy = new Tidy();
        tidy.setQuiet(true);
        tidy.setShowWarnings(false);
        org.w3c.dom.Document root = tidy.parseDOM(is, null);
        Element rawDoc = root.getDocumentElement();

        String title = getTitle(rawDoc);

        String text = getBody(rawDoc);
        /*
         * Eat consecutive whitespace characters
         */
        //     text = text.replaceAll("\\s+", " ");

        if ((title != null) && (!title.equals(""))) {
            doc.add(new Field("title", title, Field.Store.YES, Field.Index.NO));
        }
        if ((text != null) && (!text.equals(""))) {
            doc.add(new Field("content", text, Field.Store.NO,
                    Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
        }
        return doc;
    }

    /**
     * Gets the title text of the HTML document.
     *
     * @rawDoc the DOM Element to extract title Node from
     *
     * @return the title text
     */
    protected String getTitle(Element rawDoc) {
        if (rawDoc == null) {
            return null;
        }

        String title = "";

        NodeList children = rawDoc.getElementsByTagName("title");
        if (children.getLength() > 0) {
            Element titleElement = ((Element) children.item(0));
            Text text = (Text) titleElement.getFirstChild();
            if (text != null) {
                title = text.getData();
            }
        }
        return title;
    }

    /**
     * Gets the body text of the HTML document.
     *
     * @rawDoc the DOM Element to extract body Node from
     *
     * @return the body text
     */
    protected String getBody(Element rawDoc) {
        if (rawDoc == null) {
            return null;
        }

        String body = "";
        NodeList children = rawDoc.getElementsByTagName("body");
        if (children.getLength() > 0) {
            body = getText(children.item(0));
        }
        return body;
    }

    /**
     * Extracts text from the DOM node.
     *
     * @param node a DOM node
     * @return the text value of the node
     */
    protected String getText(Node node) {
        NodeList children = node.getChildNodes();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            switch (child.getNodeType()) {
                case Node.ELEMENT_NODE:
                    sb.append(getText(child));
                    sb.append(" ");
                    break;
                case Node.TEXT_NODE:
                    sb.append(((Text) child).getData());
                    break;
            }
        }
        return sb.toString().trim();
    }
}
